package configs

import (
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"github.com/spf13/viper"
	"log"
	"strings"
	"time"
)

// nacos
type Nacos struct {
	// Nacos 服务器的配置
	Scheme      string `json:"scheme"`
	Host        string `json:"host"`
	Port        uint64 `json:"port"`
	ContextPath string `json:"contextPath"`

	// 客户端配置
	Username            string `json:"username"`
	Password            string `json:"password"`
	Namespace           string `json:"namespace"`
	DataId              string `json:"dataId"`
	Group               string `json:"group"`
	NotLoadCacheAtStart bool   `json:"notLoadCacheAtStart"`
	TimeoutMs           uint64 `json:"timeoutMs"`       // 超时时间
	UpdateThreadNum     int    `json:"updateThreadNum"` // 更新线程数
	LogDir              string `json:"logDir"`          // 本地日志目录
	CacheDir            string `json:"cacheDir"`        // 本地缓存目录
	LogLevel            string `json:"logLevel"`
}

func getNacosConfig(configClient config_client.IConfigClient, nacos *Nacos) {
	// 获取配置
	content, err := configClient.GetConfig(vo.ConfigParam{
		DataId: nacos.DataId, // 配置的 Data ID
		Group:  nacos.Group,  // 配置的 Group
	})
	if err != nil {
		log.Fatalf("Getting Conf Err: %v", err)
		panic(err)
	}

	viper.SetConfigType("yaml") // 根据配置格式设置
	err = viper.ReadConfig(strings.NewReader(content))
	if err != nil {
		log.Fatalf("Failed to read config using Viper: %v", err)
	}

	_, err = loadConfig()
	// 打印配置内容
	fmt.Printf("Getting %v Nacos Config Content: %v", viper.GetString("app.name"), content)
}

// 监听器，监听Nacos配置中心数据变化
func listenNacosConfig(configClient config_client.IConfigClient, nacos *Nacos) {
	// 如果你想监听配置变化，使用监听器
	err := configClient.ListenConfig(vo.ConfigParam{
		DataId: nacos.DataId,
		Group:  nacos.Group,
		OnChange: func(namespace, group, dataId, data string) {
			fmt.Printf("配置已变化，namespace: %s, group: %s, dataId: %s, 新的配置内容: %s\n", namespace, group, dataId, data)
		},
	})
	if err != nil {
		log.Fatalf("Listen Conf Err: %v", err)
	}

	//select 阻塞状态，等待配置更新或其他事件
	select {
	case <-time.After(30 * time.Second):
		fmt.Println("Timeout reached, exiting.")
	}
}

// 获取nacos客户端配置
func getClientConfig() *constant.ClientConfig {
	// Nacos 服务器的配置
	nacos := EnvConfig.Nacos
	// 客户端配置
	return &constant.ClientConfig{
		NamespaceId:         nacos.Namespace,           // 默认 namespace 如果不需要命名空间，可以留空
		TimeoutMs:           nacos.TimeoutMs,           // 连接超时
		Username:            nacos.Username,            // Nacos 认证的用户名
		Password:            nacos.Password,            // Nacos 认证的密码
		NotLoadCacheAtStart: nacos.NotLoadCacheAtStart, // 启动时不加载缓存
		UpdateThreadNum:     nacos.UpdateThreadNum,     // 更新线程数
		LogDir:              nacos.LogDir,              // 本地日志目录
		CacheDir:            nacos.CacheDir,            // 本地缓存目录
		LogLevel:            nacos.LogLevel,            // 日志级别
	}
}

// 连接Nacos
func InitNacos() {
	// Nacos 服务器的配置
	nacos := EnvConfig.Nacos

	// Nacos服务器地址
	serverConfig := []constant.ServerConfig{
		{
			IpAddr:      nacos.Host,
			Port:        nacos.Port,
			ContextPath: nacos.ContextPath,
		},
	}

	// 创建 Nacos 客户端
	configClient, err := clients.NewConfigClient(vo.NacosClientParam{
		ClientConfig:  getClientConfig(),
		ServerConfigs: serverConfig,
	})

	if err != nil {
		log.Fatalf("Nacos Start Up  Error : %v", err)
		panic(err)
	}

	getNacosConfig(configClient, &nacos)

	go listenNacosConfig(configClient, &nacos)

}
